/**
 * @file tcu.h
 * @brief TCU设备主头文件
 * @details 定义了TCU设备的核心数据结构、常量和函数接口
 * @author 开发者
 * @date 2024
 * @version 1.0.0
 */

#ifndef TCU_H
#define TCU_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <pthread.h>
#include "../../third_party/cJSON/cJSON.h"

#include "config_manager.h"

/**
 * @name TCU版本信息
 * @{
 */
#define TCU_VERSION "1.0.0"        /**< TCU版本号 */
#define TCU_BUILD_DATE __DATE__    /**< 编译日期 */
#define TCU_BUILD_TIME __TIME__    /**< 编译时间 */
/** @} */

/**
 * @name 默认配置常量
 * @{
 */
#define TCU_DEFAULT_CONFIG_DIR "config"              /**< 默认配置目录 */
#define TCU_DEFAULT_REPORT_INTERVAL 30               /**< 默认数据上报间隔(秒) */
#define TCU_DEFAULT_MAX_RECONNECT_ATTEMPTS 10        /**< 默认最大重连次数 */
#define TCU_DEFAULT_RECONNECT_INTERVAL 5             /**< 默认重连间隔(秒) */
/** @} */

/**
 * @brief TCU设备状态枚举
 * @details 定义了TCU设备的各种运行状态
 */
typedef enum {
    TCU_STATE_INIT = 0,        /**< 初始化状态 */
    TCU_STATE_DISCONNECTED,    /**< 断开连接状态 */
    TCU_STATE_CONNECTING,      /**< 连接中状态 */
    TCU_STATE_CONNECTED,       /**< 已连接状态 */
    TCU_STATE_REGISTERING,     /**< 注册中状态 */
    TCU_STATE_REGISTERED,      /**< 已注册状态 */
    TCU_STATE_RUNNING,         /**< 运行中状态 */
    TCU_STATE_ERROR,           /**< 错误状态 */
    TCU_STATE_SHUTDOWN         /**< 关闭中状态 */
} tcu_state_t;

/**
 * @brief TCU设备信息结构体
 * @details 存储设备的基本信息，包括产品密钥、设备名称等
 */
typedef struct {
    char product_key[64];      /**< 产品密钥 */
    char device_name[128];     /**< 设备名称 */
    char device_secret[64];    /**< 设备密钥 */
    char product_secret[64];   /**< 产品密钥 */
    char client_id[128];       /**< 客户端ID */
} tcu_device_info_t;

/**
 * @brief MQTT配置结构体
 * @details 存储MQTT连接相关的配置信息
 */
typedef struct {
    char broker_host[256];     /**< MQTT代理服务器地址 */
    int broker_port;           /**< MQTT代理服务器端口 */
    char username[128];        /**< MQTT用户名 */
    char password[128];        /**< MQTT密码 */
    int keepalive;             /**< 心跳间隔(秒) */
    bool clean_session;        /**< 是否清理会话 */
    int qos;                   /**< 服务质量等级 */
    bool retain;               /**< 是否保留消息 */
} tcu_mqtt_config_t;

// 数据配置结构
typedef struct {
    int report_interval;
    int max_properties_per_report;
    bool enable_auto_register;
    bool enable_auto_reconnect;
    int reconnect_interval;
    int max_reconnect_attempts;
} tcu_data_config_t;

// TCU主结构
typedef struct {
    // 基本信息
    tcu_state_t state;
    tcu_device_info_t device_info;
    tcu_mqtt_config_t mqtt_config;
    tcu_data_config_t data_config;
    
    // 配置管理
    config_manager_t config_manager;
    
    // MQTT客户端
    void *mqtt_client;  // 实际类型为MQTTClient
    
    // 统计信息
    int64_t start_time;
    int64_t last_heartbeat;
    int message_sent_count;
    int message_received_count;
    int reconnect_count;
    
    // 控制标志
    volatile bool running;
    volatile bool should_reconnect;
    
    // 线程
    pthread_t data_report_thread;
    pthread_t heartbeat_thread;
    pthread_mutex_t state_mutex;
    pthread_mutex_t data_mutex;
} tcu_t;

// 函数声明

/**
 * @brief 初始化TCU设备
 * @param tcu TCU设备结构
 * @param config_dir 配置目录
 * @return 成功返回0，失败返回-1
 */
int tcu_init(tcu_t *tcu, const char *config_dir);

/**
 * @brief 清理TCU设备
 * @param tcu TCU设备结构
 */
void tcu_cleanup(tcu_t *tcu);

/**
 * @brief 启动TCU设备
 * @param tcu TCU设备结构
 * @return 成功返回0，失败返回-1
 */
int tcu_start(tcu_t *tcu);

/**
 * @brief 停止TCU设备
 * @param tcu TCU设备结构
 */
void tcu_stop(tcu_t *tcu);

/**
 * @brief 设置设备状态
 * @param tcu TCU设备结构
 * @param state 新状态
 */
void tcu_set_state(tcu_t *tcu, tcu_state_t state);

/**
 * @brief 获取设备状态
 * @param tcu TCU设备结构
 * @return 当前状态
 */
tcu_state_t tcu_get_state(tcu_t *tcu);

/**
 * @brief 设备注册
 * @param tcu TCU设备结构
 * @param type 注册类型
 * @return 成功返回0，失败返回-1
 */
int tcu_device_register(tcu_t *tcu, const char *type);

/**
 * @brief 设备注销
 * @param tcu TCU设备结构
 * @return 成功返回0，失败返回-1
 */
int tcu_device_unregister(tcu_t *tcu);

/**
 * @brief 获取物模型
 * @param tcu TCU设备结构
 * @param model_type 模型类型
 * @return 成功返回0，失败返回-1
 */
int tcu_get_thing_model(tcu_t *tcu, const char *model_type);

/**
 * @brief 上报属性数据
 * @param tcu TCU设备结构
 * @param properties 属性JSON对象
 * @return 成功返回0，失败返回-1
 */
int tcu_report_properties(tcu_t *tcu, cJSON *properties);

/**
 * @brief 上报单个属性
 * @param tcu TCU设备结构
 * @param identifier 属性标识符
 * @param value 属性值
 * @return 成功返回0，失败返回-1
 */
int tcu_report_property(tcu_t *tcu, const char *identifier, const char *value);

/**
 * @brief 上报事件
 * @param tcu TCU设备结构
 * @param identifier 事件标识符
 * @param output_data 输出数据JSON对象
 * @param call_type 调用类型
 * @return 成功返回0，失败返回-1
 */
int tcu_report_event(tcu_t *tcu, const char *identifier, cJSON *output_data, const char *call_type);

/**
 * @brief 处理属性设置
 * @param tcu TCU设备结构
 * @param identifier 属性标识符
 * @param value 属性值
 * @return 成功返回0，失败返回-1
 */
int tcu_handle_property_set(tcu_t *tcu, const char *identifier, const char *value);

/**
 * @brief 处理服务调用
 * @param tcu TCU设备结构
 * @param identifier 服务标识符
 * @param input_params 输入参数JSON对象
 * @param output_params 输出参数JSON对象
 * @return 成功返回0，失败返回-1
 */
int tcu_handle_service_call(tcu_t *tcu, const char *identifier, cJSON *input_params, cJSON *output_params);

/**
 * @brief 处理设备升级
 * @param tcu TCU设备结构
 * @param update_data 升级数据JSON对象
 * @return 成功返回0，失败返回-1
 */
int tcu_handle_device_update(tcu_t *tcu, cJSON *update_data);

/**
 * @brief 打印设备统计信息
 * @param tcu TCU设备结构
 */
void tcu_print_stats(tcu_t *tcu);

/**
 * @brief 获取设备运行时间
 * @param tcu TCU设备结构
 * @return 运行时间（秒）
 */
int64_t tcu_get_uptime(tcu_t *tcu);

/**
 * @brief 状态转字符串
 * @param state 状态
 * @return 状态字符串
 */
const char* tcu_state_to_string(tcu_state_t state);

// 回调函数类型定义
typedef void (*tcu_message_callback_t)(const char *topic, const char *message, int qos);
typedef void (*tcu_connect_callback_t)(bool success);
typedef void (*tcu_disconnect_callback_t)(void);

/**
 * @brief 设置消息回调函数
 * @param tcu TCU设备结构
 * @param callback 回调函数
 */
void tcu_set_message_callback(tcu_t *tcu, tcu_message_callback_t callback);

/**
 * @brief 设置连接回调函数
 * @param tcu TCU设备结构
 * @param callback 回调函数
 */
void tcu_set_connect_callback(tcu_t *tcu, tcu_connect_callback_t callback);

/**
 * @brief 设置断开连接回调函数
 * @param tcu TCU设备结构
 * @param callback 回调函数
 */
void tcu_set_disconnect_callback(tcu_t *tcu, tcu_disconnect_callback_t callback);

#endif // TCU_H
